package com.mf.controller;

import com.mf.bo.PositionsDetailBo;
import com.mf.entity.CodeHistory;
import com.mf.entity.Positions;
import com.mf.result.Result;
import com.mf.service.ICodeHistoryService;
import com.mf.service.ICodeService;
import com.mf.service.IPositionsService;
import com.mf.vo.positions.PositionsDetailVo;
import com.mf.vo.positions.PositionsKListVo;
import com.mf.vo.positions.PositionsVo;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 持仓前端控制
 *
 * @author mf
 * @since 2024-06-08
 */
@RestController
@RequestMapping("/positions")
public class PositionsController {
    @Resource
    private IPositionsService positionsService;

    @Resource
    private ICodeHistoryService codeHistoryService;

    @Resource
    private ICodeService codeService;

    /**
     * 查询持仓数据
     */
    @PostMapping("/findPositionsDetail")
    public Result<PositionsDetailVo> findPositionsDetail(@Valid @RequestBody PositionsDetailBo positionsDetailBo) {

        final List<Positions> positionsDetail = positionsService.findPositionsDetail(positionsDetailBo);

        if (positionsDetail == null || positionsDetail.isEmpty()) {
            return Result.success();
        }

        // 根据持仓数据获取按代码分组的k线数据
        Map<String, List<CodeHistory>> codeHistoryList = codeHistoryService.findAllDateByDm(positionsDetail);

        // 获取代码
        List<PositionsVo> pVo = codeService.findDmList(positionsDetail);

        final PositionsDetailVo positionsDetailVo = new PositionsDetailVo();

//        // 设置 PositionsVo
        final List<PositionsVo> positionsVos = setPositionsVo(codeHistoryList, positionsDetail, pVo);

        positionsDetailVo.setPositionsVo(positionsVos);
        return Result.success(positionsDetailVo);
    }

    private List<PositionsVo> setPositionsVo(Map<String, List<CodeHistory>> codeHistoryList,
                                             List<Positions> positionsDetail, List<PositionsVo> pVo) {
        List<PositionsVo> positionsVos = new ArrayList<>();


        codeHistoryList.forEach((k, v) -> {
            final Optional<Positions> firstPos =
                    positionsDetail.stream().filter(Positions -> k.equals(Positions.getDm())).findFirst();

            final Optional<PositionsVo> positionsVo1 =
                    pVo.stream().filter(PositionsVo -> k.equals(PositionsVo.getDm())).findFirst();

            PositionsVo positionsVo2 = new PositionsVo();
            if (firstPos.isPresent() && positionsVo1.isPresent()) {
                positionsVo2.setDm(firstPos.get().getDm());
                positionsVo2.setUserId(firstPos.get().getUserId());
                positionsVo2.setDate(firstPos.get().getDate());
                positionsVo2.setPrice(firstPos.get().getPrice());
                positionsVo2.setAmount(firstPos.get().getAmount());
                positionsVo2.setMc(positionsVo1.get().getMc());
                positionsVo2.setUserName(positionsVo1.get().getUserName());
                // 获取盈亏
                BigDecimal profit =
                        (v.get(v.size() - 1).getC().subtract(positionsVo2.getPrice())).divide(positionsVo2.getPrice(), 3,
                        RoundingMode.HALF_UP).multiply(new BigDecimal(100));

                positionsVo2.setProfit(profit + "%");

                // 获取持仓天数
                positionsVo2.setDays(v.size());

            }

            final List<PositionsKListVo> positionsKListVoList = getPositionsKListVos(v, positionsVo2);
            positionsVo2.setKList(positionsKListVoList);
            positionsVos.add(positionsVo2);
        });
        return positionsVos;
    }

    private static List<PositionsKListVo> getPositionsKListVos(List<CodeHistory> v, PositionsVo positionsVo2) {
        List<PositionsKListVo> positionsKListVoList = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date1 = dateFormat.parse(positionsVo2.getDate());

            for (int i = 0; i < v.size(); i++) {
                final CodeHistory codeHistory = v.get(i);
                Date date2 = dateFormat.parse(codeHistory.getD());
                if (date1.equals(date2) || date2.after(date1)) {
                    final PositionsKListVo positionsKListVo = new PositionsKListVo();

                    String profit = "";
                    // 计算收益率 (该收益率是平均持仓成本后的收益率)
                    if (date1.equals(date2)) {
                        profit = (codeHistory.getC().subtract(positionsVo2.getPrice()).divide(positionsVo2.getPrice()
                                , 3,
                                RoundingMode.HALF_UP).multiply(new BigDecimal(100))) + "%";
                    } else {
                        // 计算收益率
                        profit = (codeHistory.getC().subtract(v.get(i - 1).getC()).divide(v.get(i - 1).getC(), 3,
                                RoundingMode.HALF_UP).multiply(new BigDecimal(100)) + "%");
                    }
                    positionsKListVo.setProfit(profit);
                    positionsKListVo.setDate(codeHistory.getD());
                    positionsKListVo.setC(codeHistory.getC());
                    positionsKListVo.setH(codeHistory.getH());
                    positionsKListVo.setL(codeHistory.getL());
                    positionsKListVo.setO(codeHistory.getO());
                    positionsKListVoList.add(positionsKListVo);
                }
            }

        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        return positionsKListVoList;
    }
}
